﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WinForms_path
{
    public partial class Form1 : Form
    {
        public  bool planning = false;
        private Thread
            thread1 = null,
            thread2 = null,
            thread3 = null,            
            thread_point = null;
        int p = 1, map;
        public Bitmap Bmp,Bmp1;
        public Graphics g,g1,g2;
        public IList< IList<Point>> obstacle = new List<IList<Point>>();
 

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //默认显示图1
            pictureBox1.Image = Image.FromFile("bitmap/1.bmp");
            panel1.SetBounds(810, 10, 200, 100);
            //设置选择列表默认值
            comboBox1.SelectedIndex = 0;
            comboBox2.SelectedIndex = 0;                      

            Control.CheckForIllegalCrossThreadCalls = false;
        }
        //
        //地图选择
        //
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            map = comboBox1.SelectedIndex;
            switch (map)
            {
                case 0: pictureBox1.Image = Image.FromFile("bitmap/1.bmp"); break;
                case 1: pictureBox1.Image = Image.FromFile("bitmap/2.bmp"); break;
                case 2: pictureBox1.Image = Image.FromFile("bitmap/3.bmp"); break;
                case 3: pictureBox1.Image = Image.FromFile("bitmap/4.bmp"); break;
                case 4: pictureBox1.Image = Image.FromFile("bitmap/5.bmp"); break;
                case 5: pictureBox1.Image = Image.FromFile("bitmap/6.bmp"); break;
                case 6: pictureBox1.Image = Image.FromFile("bitmap/7.bmp"); break;

            }
            panel1.SetBounds(810, 10, 200, 100);
        }
        //开始
        private void button_start_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled == false)
            {

                Bmp = new Bitmap(pictureBox1.Image);
                
                // pictureBox1.Image = Bmp;//在pictureBox1的控件里绘制Bmp
                g = Graphics.FromImage(Bmp);//在Bmp上创建一张画布
                

                thread1 = new Thread(new ThreadStart(DrawPath ));//新线程执行Path函数

                timer1.Enabled = true;
                planning = true ;
                thread1.Start();//线程开始
                // MessageBox.Show("线程开始");

            }
            button_start.Enabled = false;
            button_pause.Enabled = true;
            

        }
        //暂停
        private void button_pause_Click(object sender, EventArgs e)
        {
            if (button_pause.Text.ToString()=="暂停")
            {
                timer1.Enabled = false;
                button_reset.Enabled = true ;
                button_pause.Text = "继续"; 
            } 
            else
            {
                timer1.Enabled = true ;
                button_reset.Enabled = false ;
                button_pause.Text = "暂停";
            }
           
        }
        //复位
        private void button_reset_Click(object sender, EventArgs e)
        {
            button_start.Enabled = true;
            button_pause.Enabled = false;
            button_reset.Enabled = false;
            comboBox1_SelectedIndexChanged(pictureBox1,EventArgs.Empty );//还原地图
            thread1.Abort();
        }
        //定时器
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!timer1.Enabled) return;
            planning = true;
            
            //MessageBox.Show("02");

        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            Bitmap b = new Bitmap( pictureBox1.Image );                       
            Color  bval=b.GetPixel(e.X, e.Y);
            int val = bval.R ;
            //MessageBox.Show("横坐标:" + e.X.ToString() + "\n纵坐标:" + e.Y.ToString()+ "\n颜色:" + bval.ToString ()+"\n颜色:" +val );
            val = 0;

            thread_point.Abort();
        }     
                    
        //
        //起点选择
        //
        private void button_StartP_Click(object sender, EventArgs e)
        {
            thread_point = new Thread(new ThreadStart(ShowSPoint));
            thread_point.Start();
            
        }
        //
        //选择起点坐标
        //
        public void ShowSPoint()
        {                 
                  
            while(true)
            {
                
                Point point = pictureBox1.PointToClient(Control.MousePosition);
                textBox_StartP_X.Text = point.X.ToString();
                textBox_StartP_Y.Text = point.Y.ToString();
            }
        } 
        //
        //终点选择
        //
        private void button_EndP_Click(object sender, EventArgs e)
        {
            thread_point = new Thread(new ThreadStart(ShowEPoint));
            thread_point.Start();
        }
        //
        //选择终点坐标
        //
        public void ShowEPoint()
        {

            while (true)
            {

                Point point = pictureBox1.PointToClient(Control.MousePosition);
                textBox_EndP_X.Text = point.X.ToString();
                textBox_EndP_Y.Text = point.Y.ToString();
            }
        }

        public void Path()
        {
            //MessageBox.Show("02");
            while (true)
            {
                if (planning)
                {
                    g.DrawLine(   //用黑色线段按顺序连接每个点（曲线）            
                        new Pen(Color.Black), //设置画笔颜色
                        new Point(p * 10, p * 20), //线段起点
                        new Point(p * 20, 30 * p));//线段终点


                    pictureBox1.Image = Bmp;
                    p++;
                    //MessageBox.Show("02");
                    planning = false;
                }
            }
        }
        ///<summary>
        /// obstacle_pro()随机障碍物的生成
        /// </summary>
        public void obstacle_pro()
        {
            int obstacle_num = Convert.ToInt32(Obstacle_Num.Text),i;
             //IList< IList<Point>> obstacle = new List<IList<Point>>();
            Random rd_x = new Random(), rd_y = new Random(); ;
            for (i=0; i < obstacle_num; i++)
            {
                ram_obstacle:

                rd_x.Next (0, Bmp.Width);
                rd_y.Next(0, Bmp.Height);
                if (Bmp.GetPixel(Convert.ToInt32(rd_x), Convert.ToInt32(rd_y)).R != 0)                
                    obstacle[i].Add(new Point(Convert.ToInt32(rd_x), Convert.ToInt32(rd_y)));                   
                 else goto ram_obstacle;
            }
        }
        ///<summary>
        /// 随机障碍物的下一步移动方向
        /// </summary>
        public  void obstacle_NextStep(object a)
        {

            int X,Y, j= Convert.ToInt16(a);
            for( int i =0; i < Convert.ToInt32(Obstacle_Num.Text); i++)
            {
                X = obstacle[i][j].X;
                Y = obstacle[i][j].Y;
                           
                Point now_p = new  Point (X, Y), next_p = new Point();
                Random ra = new Random ();
                obs_next_step:
                ra.Next(0,8);
                switch (Convert.ToInt16(ra))
                {
                case 0:  next_p.X = now_p.X; next_p.Y = now_p.Y - 1; break;
                case 1: next_p.X = now_p.X+1; next_p.Y = now_p.Y-1; break;
                case 2: next_p.X = now_p.X+1; next_p.Y = now_p.Y; break;
                case 3: next_p.X = now_p.X+1; next_p.Y = now_p.Y+1; break;
                case 4: next_p.X = now_p.X; next_p.Y = now_p.Y+1; break;
                case 5: next_p.X = now_p.X-1; next_p.Y = now_p.Y+1; break;
                case 6: next_p.X = now_p.X-1; next_p.Y = now_p.Y; break;
                case 7: next_p.X = now_p.X-1; next_p.Y = now_p.Y-1; break;
                }
                if (next_p.X >= 0 && next_p.Y >= 0)
                    if (Bmp.GetPixel(next_p.X, next_p.Y).R != 0)
                    obstacle[i].Add(next_p);
                    else goto obs_next_step;
                 else goto obs_next_step;

            }

        }
        ///<summary>
        /// 障碍物开始移动
        /// </summary>
        public void obstacle_move()
        {
            Thread[] obs_t = new Thread[Convert.ToInt32(Obstacle_Num.Text)];
            for (int i = 0; i < obs_t .Length; i++)
            {
                obs_t[i] = new Thread(new ParameterizedThreadStart(obstacle_NextStep));
                obs_t[i].Start(i);
            }

        }
        ///<summary>
        ///路径规划函数 
        ///</summary>
        public void DrawPath()
        {
            
            AStarRoutePlanner aStarRoutePlanner = new AStarRoutePlanner();
            IList<Point> obstaclePoints = new List<Point>();
            
            for (int Y = 0; Y < Bmp.Height; Y++)
                for (int X = 0; X < Bmp.Width; X++)
                    if (Bmp.GetPixel(X, Y).R == 0)
                        obstaclePoints.Add(new Point(X, Y));//添加障碍物位置
            /*
            obstaclePoints.Add(new Point(2, 4));
            obstaclePoints.Add(new Point(3, 4));
            obstaclePoints.Add(new Point(4, 4));
            obstaclePoints.Add(new Point(5, 4));
            obstaclePoints.Add(new Point(6, 4));
            */
            aStarRoutePlanner.Initialize(obstaclePoints);
            IList<Point> route = aStarRoutePlanner.Plan(
                new Point(Convert.ToInt32(textBox_StartP_X.Text), Convert.ToInt32(textBox_StartP_Y.Text)), 
                new Point(Convert.ToInt32(textBox_EndP_X.Text), Convert.ToInt32(textBox_EndP_Y.Text)));
            IList<Point> route1 = aStarRoutePlanner.Plan(new Point(400,10),new Point(300,20));

            int r_num = 0,min=0, max = 0;
            if (route.Count > route1.Count)
            {
                max = route.Count;
                min = route1.Count;
            }
            else
            {
                max = route1.Count;
                min = route.Count;
            }

            while (true)
            {
                if (planning && (r_num < max) )
                {
                    if (r_num < min)
                    {
                        Bmp.SetPixel(route[r_num].X, route[r_num].Y, Color.Green);
                        Bmp.SetPixel(route1[r_num].X, route1[r_num].Y, Color.Green);
                    }
                    else if(route.Count > route1.Count)
                        Bmp.SetPixel(route[r_num].X, route[r_num].Y, Color.Green);
                    else Bmp.SetPixel(route1[r_num].X, route1[r_num].Y, Color.Green);
                                        
                    pictureBox1.Image = Bmp;
                    // g.DrawLine(new Pen(Color.Red), new Point (route[r_num].X, route[r_num].Y), new Point(route[r_num+1].X,route[r_num+1].Y) );
                    // pictureBox1.Image = Bmp;
                    r_num++;
                    if (r_num == route.Count)
                    {
                        MessageBox.Show("结束");
                        g.Dispose();//释放画布资源
                    }
                    planning = false;
                }
                
            }            
        }
        //

        


    }
}



          
                
          
        



